package com.qiangesoft.blog.core.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangesoft.blog.common.constants.FieldConstants;
import com.qiangesoft.blog.common.constants.RedisConstants;
import com.qiangesoft.blog.common.mvc.PageQuery;
import com.qiangesoft.blog.common.mvc.PageResultVO;
import com.qiangesoft.blog.common.result.ResponseResult;
import com.qiangesoft.blog.common.utils.BeanCopyUtils;
import com.qiangesoft.blog.common.utils.DateUtils;
import com.qiangesoft.blog.common.utils.IpUtils;
import com.qiangesoft.blog.common.utils.PageUtils;
import com.qiangesoft.blog.core.entity.*;
import com.qiangesoft.blog.core.mapper.*;
import com.qiangesoft.blog.core.pojo.dto.ArticleDTO;
import com.qiangesoft.blog.core.pojo.query.ArticleQueryDTO;
import com.qiangesoft.blog.core.pojo.vo.*;
import com.qiangesoft.blog.core.service.IBlogArticleService;
import com.qiangesoft.blog.core.service.IBlogCommentService;
import com.qiangesoft.blog.core.strategy.context.SearchStrategyContext;
import com.qiangesoft.blog.core.utils.ElasticsearchUtils;
import com.qiangesoft.blog.system.entity.SysUser;
import com.qiangesoft.blog.system.exception.BusinessException;
import com.qiangesoft.blog.system.mapper.SysUserMapper;
import com.qiangesoft.blog.system.pojo.vo.SysUserDetailVO;
import com.qiangesoft.blog.system.redis.RedisService;
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
import com.vladsch.flexmark.util.data.MutableDataSet;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.qiangesoft.blog.common.constants.Constants.*;
import static com.qiangesoft.blog.common.constants.RedisConstants.*;
import static com.qiangesoft.blog.common.result.ResultCode.*;

/**
 * <p>
 * 博客文章 服务实现类
 * </p>
 *
 * @author qiange
 * @since 2023-06-05
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BlogArticleServiceImpl extends ServiceImpl<BlogArticleMapper, BlogArticle> implements IBlogArticleService {

    private final SysUserMapper sysUserMapper;

    private final BlogCategoryMapper categoryMapper;

    private final RedisService redisService;

    private final BlogTagMapper blogTagMapper;

    private final BlogArticleTagMapper blogArticleTagMapper;

    private final BlogCommentMapper commentMapper;

    private final IBlogCommentService blogCommentService;

    private final SearchStrategyContext searchStrategyContext;

    private final RestTemplate restTemplate;

    private final HttpServletRequest request;

    private final ElasticsearchUtils elasticsearchUtils;

    @Value("${baidu.url}")
    private String baiduUrl;

    @Override
    public PageResultVO<ArticleListVO> listArticle(PageQuery pageQuery, ArticleQueryDTO articleQuery) {
        PageResultVO<ArticleListVO> pageResultVO = new PageResultVO<>();
        Integer pageNum = pageQuery.getPageNum();
        Integer pageSize = pageQuery.getPageSize();
        pageResultVO.setPageNum(pageNum);
        pageResultVO.setPageSize(pageSize);

        Page<ArticleListVO> page = baseMapper.selectArticle(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), articleQuery);
        pageResultVO.setTotal(page.getTotal());
        pageResultVO.setPages(page.getPages());
        pageResultVO.setResults(page.getRecords());
        return pageResultVO;
    }

    /**
     * 后台获取文章详情
     *
     * @return
     */
    @Override
    public ResponseResult getArticleById(Long id) {
        ArticleDTO articleDTO = baseMapper.selectPrimaryKey(id);
        articleDTO.setTags(blogTagMapper.selectByArticleId(id));
        return ResponseResult.success(articleDTO);
    }

    /**
     * 添加文章
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult insertArticle(ArticleDTO article) {
        BlogArticle blogArticle = BeanCopyUtils.copyObject(article, BlogArticle.class);
        blogArticle.setUserId(StpUtil.getLoginIdAsLong());
        //添加分类
        Long categoryId = savaCategory(article.getCategoryName());
        //添加标签
        List<Long> tagList = getTagsList(article);

        blogArticle.setCategoryId(categoryId);

        int insert = baseMapper.insert(blogArticle);
        if (insert > 0) {
            blogTagMapper.saveArticleTags(blogArticle.getId(), tagList);
        }
        return ResponseResult.success();
    }

    /**
     * 修改文章
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updateArticle(ArticleDTO article) {
        BlogArticle blogArticle = baseMapper.selectById(article.getId());
        if (ObjectUtil.isNull(blogArticle)) {
            throw new BusinessException(ARTICLE_NOT_EXIST.getDesc());
        }

        //添加分类
        Long categoryId = savaCategory(article.getCategoryName());
        //添加标签
        List<Long> tagList = getTagsList(article);

        blogArticle = BeanCopyUtils.copyObject(article, BlogArticle.class);
        blogArticle.setCategoryId(categoryId);
        blogArticle.setUserId(StpUtil.getLoginIdAsLong());
        baseMapper.updateById(blogArticle);

        //先删出所有标签
        blogTagMapper.deleteByArticleIds(Collections.singletonList(blogArticle.getId()));
        //然后新增标签
        blogTagMapper.saveArticleTags(blogArticle.getId(), tagList);

        return ResponseResult.success();
    }

    /**
     * 删除文章
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteArticle(Long id) {
        int row = baseMapper.deleteById(id);
        if (row > 0) {
            this.deleteAfter(Collections.singletonList(id));
        }
        return ResponseResult.success();
    }

    /**
     * 批量删除文章
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteBatchArticle(List<Long> ids) {
        int rows = baseMapper.deleteBatchIds(ids);
        if (rows > 0) {
            this.deleteAfter(ids);
        }
        return ResponseResult.success();
    }

    /**
     * 置顶文章
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult putTopArticle(ArticleDTO article) {
        baseMapper.putTopArticle(article);
        return ResponseResult.success();
    }


    /**
     * 文章百度推送
     *
     * @return
     */
    @Override
    public ResponseResult articleSeo(List<Long> ids) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("Host", "data.zz.baidu.com");
        headers.add("User-Agent", "curl/7.12.1");
        headers.add("Content-Length", "83");
        headers.add("Content-Type", "text/plain");

        ids.forEach(item -> {
            String url = "http://www.shiyit.com/article/" + item;
            HttpEntity<String> entity = new HttpEntity<>(url, headers);
            restTemplate.postForObject(baiduUrl, entity, String.class);
        });
        return ResponseResult.success();
    }

    /**
     * 抓取文章
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult reptile(String url) {
        try {
            Document document = Jsoup.connect(url).get();
            Elements title = document.getElementsByClass("title-article");
            Elements tags = document.getElementsByClass("tag-link");
            Elements content = document.getElementsByClass("article_content");
            if (StringUtils.isBlank(content.toString())) {
                throw new BusinessException(CRAWLING_ARTICLE_FAILED.getDesc());
            }

            //爬取的是HTML内容，需要转成MD格式的内容
            String newContent = content.get(0).toString().replaceAll("<code>", "<code class=\"lang-java\">");
            MutableDataSet options = new MutableDataSet();
            String markdown = FlexmarkHtmlConverter.builder(options).build().convert(newContent)
                    .replace("lang-java", "java");

            //文章封面图片 由https://api.btstu.cn/该网站随机获取
            String strResult = restTemplate.getForObject(IMG_URL_API, String.class);
            JSONObject jsonObject = JSON.parseObject(strResult);
            Object imgUrl = jsonObject.get("imgurl");

            BlogArticle entity = BlogArticle.builder().userId(7L).contentMd(markdown)
                    .categoryId(OTHER_CATEGORY_ID).isOriginal(false).originalUrl(url)
                    .title(title.get(0).text()).avatar(imgUrl.toString()).content(newContent).build();

            baseMapper.insert(entity);
            //为该文章添加标签
            List<Long> tagsId = new ArrayList<>();
            tags.forEach(item -> {
                String tag = item.text();
                BlogTag result = blogTagMapper.selectOne(new QueryWrapper<BlogTag>().eq(FieldConstants.NAME, tag));
                if (result == null) {
                    result = BlogTag.builder().name(tag).build();
                    blogTagMapper.insert(result);
                }
                tagsId.add(result.getId());
            });
            blogTagMapper.saveArticleTags(entity.getId(), tagsId);

            log.info("文章抓取成功，内容为:{}", JSON.toJSONString(entity));
        } catch (IOException e) {
            throw new BusinessException(e);
        }
        return ResponseResult.success();
    }

    /**
     * 发布或下架文章
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishAndShelf(ArticleDTO article) {
        baseMapper.publishAndShelf(article);
    }

    @Override
    public ResponseResult randomImg() {
        //文章封面图片 由https://api.btstu.cn/该网站随机获取
        String result = restTemplate.getForObject(IMG_URL_API, String.class);
        Object imgUrl = JSON.parseObject(result).get("imgurl");
        return ResponseResult.success(imgUrl);
    }

    //    ----------web端方法开始-------

    @Override
    public PageResultVO<ArticlePreviewVO> listWebArticle(PageQuery pageQuery, ArticleQueryDTO articleQuery) {
        Integer pageNum = pageQuery.getPageNum();
        Integer pageSize = pageQuery.getPageSize();
        PageResultVO<ArticlePreviewVO> pageResult = new PageResultVO<>();
        pageResult.setPageNum(pageNum);
        pageResult.setPageSize(pageSize);

        LambdaQueryWrapper<BlogArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(articleQuery.getTitle()), BlogArticle::getTitle, articleQuery.getTitle())
                .eq(!ObjectUtils.isEmpty(articleQuery.getCategoryId()), BlogArticle::getCategoryId, articleQuery.getCategoryId())
                .eq(BlogArticle::getIsPublish, true)
                .orderByDesc(BlogArticle::getIsStick);

        // 通过标签查询
        Long tagId = articleQuery.getTagId();
        if (!ObjectUtils.isEmpty(tagId)) {
            LambdaQueryWrapper<BlogArticleTag> tagWrapper = new LambdaQueryWrapper<>();
            tagWrapper.eq(BlogArticleTag::getTagId, tagId);
            List<Long> articleIds = blogArticleTagMapper.selectList(tagWrapper).stream().map(BlogArticleTag::getArticleId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(articleIds)) {
                return pageResult;
            }
            queryWrapper.in(BlogArticle::getId, articleIds);
        }

        Page<BlogArticle> page = baseMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);
        List<BlogArticle> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return pageResult;
        }

        Set<Long> categoryIds = records.stream().map(BlogArticle::getCategoryId).collect(Collectors.toSet());
        Map<Long, String> categoryMap = categoryMapper.selectBatchIds(categoryIds).stream().collect(Collectors.toMap(BlogCategory::getId, BlogCategory::getName));

        List<ArticlePreviewVO> voList = new ArrayList<>();
        for (BlogArticle record : records) {
            ArticlePreviewVO vo = new ArticlePreviewVO();
            vo.setId(record.getId());
            vo.setTitle(record.getTitle());
            vo.setAvatar(record.getAvatar());
            vo.setContent(record.getContent());
            vo.setIsStick(record.getIsStick());
            vo.setCreateTime(DateUtils.localDateTimeToDate(record.getCreateTime()));
            vo.setCategoryId(record.getCategoryId());
            vo.setQuantity(record.getQuantity());
            vo.setCategoryName(categoryMap.get(record.getCategoryId()));

            vo.setCommentNum(blogCommentService.countCommentByArticleId(record.getId()));
            vo.setBlogTagList(blogTagMapper.findByArticleIdToTags(record.getId()));
            voList.add(vo);
        }
        pageResult.setTotal(page.getTotal());
        pageResult.setPages(page.getPages());
        pageResult.setResults(voList);
        return pageResult;
    }

    @Override
    public List<ArticlePreviewVO> listHotArticle(Integer limit) {
        List<ArticlePreviewVO> previewVOList = baseMapper.selectHotArticle(true, limit);
        previewVOList.forEach(item -> item.setBlogTagList(blogTagMapper.findByArticleIdToTags(item.getId())));
        return previewVOList;
    }

    /**
     * 获取文章详情
     *
     * @return
     */
    @Override
    public ArticleInfoVO webArticleInfo(Long id) {
        BlogArticle article = baseMapper.selectById(id);

        ArticleInfoVO blogArticle = new ArticleInfoVO();
        BeanUtils.copyProperties(article, blogArticle);
        blogArticle.setCreateTime(DateUtils.localDateTimeToDate(article.getCreateTime()));

        // 作者
        Long userId = article.getUserId();
        SysUser sysUser = sysUserMapper.selectById(userId);
        blogArticle.setAuthor(sysUser);

        //标签
        List<BlogTagVO> tags = blogTagMapper.findByArticleIdToTags(blogArticle.getId());
        blogArticle.setTagList(tags);
        //分类
        BlogCategory category = categoryMapper.selectById(blogArticle.getCategoryId());
        blogArticle.setCategory(category);
        //评论
        QueryWrapper<BlogComment> queryWrapper = new QueryWrapper<BlogComment>()
                .eq(FieldConstants.ARTICLE_ID, blogArticle.getId()).orderByDesc(FieldConstants.CREATE_TIME);
        List<BlogComment> list = commentMapper.selectList(queryWrapper);
        blogArticle.setComments(list);

        //最新文章
        List<LatestArticleVO> blogArticles = baseMapper.getNewArticles(id, true);
        blogArticle.setNewestArticleList(blogArticles);

        // 查询上一篇下一篇文章
        LatestArticleVO lastArticle = baseMapper.getNextOrLastArticle(id, 0, true);
        blogArticle.setLastArticle(lastArticle);
        LatestArticleVO nextArticle = baseMapper.getNextOrLastArticle(id, 1, true);
        blogArticle.setNextArticle(nextArticle);

        //相关推荐
        List<LatestArticleVO> recommendArticleList = baseMapper.listRecommendArticles(id);
        blogArticle.setRecommendArticleList(recommendArticleList);

        // 封装点赞量和浏览量
        blogArticle.setLikeCount((Integer) redisService.hGet(RedisConstants.ARTICLE_LIKE_COUNT, blogArticle.getId().toString()));

        //校验私密文章是否已经进行过验证
        if (blogArticle.getIsSecret()) {
            List<Object> cacheList = redisService.getCacheList(RedisConstants.CHECK_CODE_IP);
            String ip = IpUtils.getIp(request);
            if (cacheList.contains(ip)) blogArticle.setIsSecret(false);
        }

        // 增加文章阅读量
        redisService.incrArticle(id.longValue(), ARTICLE_READING);
        return blogArticle;
    }

    /**
     * 获取分类or标签文章
     *
     * @return
     */
    @Override
    public ResponseResult condition(Long categoryId, Long tagId, Integer pageSize) {
        Map<String, Object> result = new HashMap<>();
        Page<ArticlePreviewVO> blogArticlePage = baseMapper.selectPreviewPage(new Page<>(PageUtils.getPageNo(), pageSize), true, categoryId, tagId);
        blogArticlePage.getRecords().forEach(item -> {
            List<BlogTagVO> tagList = blogTagMapper.findByArticleIdToTags(item.getId());
            item.setBlogTagList(tagList);
        });
        String name;
        if (categoryId != null) {
            name = categoryMapper.selectById(categoryId).getName();
        } else {
            name = blogTagMapper.selectById(tagId).getName();
            redisService.incrArticle(tagId, TAG_CLICK_VOLUME);
        }
        result.put(FieldConstants.NAME, name);
        result.put(RECORDS, blogArticlePage.getRecords());
        return ResponseResult.success(result);
    }

    /**
     * 获取归档
     *
     * @return
     */
    @Override
    public ResponseResult archive() {
        Page<ArticlePreviewVO> articlePage = baseMapper.selectArchivePage(new Page<>(PageUtils.getPageNo(), PageUtils.getPageSize()), true);
        return ResponseResult.success(articlePage);
    }

    /**
     * 搜索文章
     *
     * @return
     */
    @Override
    public ResponseResult searchArticle(String keywords) {
        if (StringUtils.isBlank(keywords)) {
            throw new BusinessException(PARAMS_ILLEGAL.getDesc());
        }
        //获取搜索模式（es搜索或mysql搜索）
//        SystemConfig systemConfig = systemConfigService.getCustomizeOne();
        String strategy = "mysql";
        //搜索逻辑
        List<ArticleSearchVO> articleSearchVOS = searchStrategyContext.executeSearchStrategy(strategy, keywords);
        return ResponseResult.success(articleSearchVOS);
    }

    /**
     * 文章点赞
     *
     * @param articleId
     * @return
     */
    @Override
    public ResponseResult articleLike(Integer articleId) {
        // 判断是否点赞
        String articleLikeKey = ARTICLE_USER_LIKE + StpUtil.getLoginId();
        if (redisService.sIsMember(articleLikeKey, articleId)) {
            // 点过赞则删除文章id
            redisService.sRemove(articleLikeKey, articleId);
            // 文章点赞量-1
            redisService.hDecr(ARTICLE_LIKE_COUNT, articleId.toString(), 1L);
        } else {
            // 未点赞则增加文章id
            redisService.sAdd(articleLikeKey, articleId);
            // 文章点赞量+1
            redisService.hIncr(ARTICLE_LIKE_COUNT, articleId.toString(), 1L);
        }
        return ResponseResult.success();
    }

    @Override
    public ArticleTimeAxisMainVO timeAxis() {
        // 查询所有文章
        LambdaQueryWrapper<BlogArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(BlogArticle::getId, BlogArticle::getTitle, BlogArticle::getIsStick, BlogArticle::getCreateTime)
                .orderByDesc(BlogArticle::getCreateTime);
        List<BlogArticle> articleList = this.list(queryWrapper);

        List<ArticleTimeAxisVO> voList = new ArrayList<>();

        // 按月分组
        Map<String, List<BlogArticle>> monthMap = articleList.stream().collect(Collectors.groupingBy(p -> DateUtils.formateDate(p.getCreateTime(), "yyyy-MM")));
        for (Map.Entry<String, List<BlogArticle>> monthEntry : monthMap.entrySet()) {
            ArticleTimeAxisVO vo = new ArticleTimeAxisVO();
            vo.setMonthTime(DateUtils.str2Date(monthEntry.getKey(), "yyyy-MM"));

            List<ArticleTimeSimpleVO> dayArticleVoList = new ArrayList<>();

            // 按天分组
            List<BlogArticle> monthArticles = monthEntry.getValue();
            Map<String, List<BlogArticle>> dayMap = monthArticles.stream().collect(Collectors.groupingBy(p -> DateUtils.formateDate(p.getCreateTime(), "MM-dd")));
            for (Map.Entry<String, List<BlogArticle>> dayEntry : dayMap.entrySet()) {
                ArticleTimeSimpleVO articleTimeSimple = new ArticleTimeSimpleVO();
                articleTimeSimple.setDayTime(dayEntry.getKey());

                List<BlogArticle> value = dayEntry.getValue();
                List<ArticleSimpleVO> articleVoList = new ArrayList<>();
                for (BlogArticle article : value) {
                    ArticleSimpleVO articleSimpleVO = new ArticleSimpleVO();
                    articleSimpleVO.setId(article.getId());
                    articleSimpleVO.setTitle(article.getTitle());
                    articleSimpleVO.setIsStick(article.getIsStick());
                    articleSimpleVO.setCreateTime(DateUtils.localDateTimeToDate(article.getCreateTime()));
                    articleVoList.add(articleSimpleVO);
                }
                articleTimeSimple.setArticleList(articleVoList);
                dayArticleVoList.add(articleTimeSimple);
            }
            dayArticleVoList.sort(Comparator.comparing(ArticleTimeSimpleVO::getDayTime).reversed());
            vo.setDayArticleList(dayArticleVoList);
            voList.add(vo);
        }
        voList.sort(Comparator.comparing(ArticleTimeAxisVO::getMonthTime).reversed());
        ArticleTimeAxisMainVO vo = new ArticleTimeAxisMainVO();
        vo.setTotal(articleList.size());
        vo.setTimeAxisList(voList);
        return vo;
    }

    @Override
    public List<BlogCategoryArticleVO> listByCategory() {
        List<BlogCategory> categoryList = categoryMapper.selectList(new LambdaQueryWrapper<>());

        LambdaQueryWrapper<BlogArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(BlogArticle::getId, BlogArticle::getCategoryId, BlogArticle::getTitle, BlogArticle::getCreateTime);
        List<BlogArticle> articleList = this.list(queryWrapper);

        Map<Long, List<BlogArticle>> map = articleList.stream().collect(Collectors.groupingBy(BlogArticle::getCategoryId));

        List<BlogCategoryArticleVO> voList = new ArrayList<>();
        for (BlogCategory blogCategory : categoryList) {
            BlogCategoryArticleVO vo = new BlogCategoryArticleVO();
            vo.setId(blogCategory.getId());
            vo.setName(blogCategory.getName());
            vo.setArticleList(map.get(blogCategory.getId()));
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 校验文章验证码(验证码通过关注公众号获取)
     *
     * @return
     */
    @Override
    public ResponseResult checkSecret(String code) {
        //校验验证码
        String key = RedisConstants.WECHAT_CODE + code;
        Object redisCode = redisService.getCacheObject(key);
        if (ObjectUtil.isNull(redisCode)) {
            throw new BusinessException(ERROR_EXCEPTION_MOBILE_CODE.getDesc());
        }

        //将ip存在redis 有效期一天，当天无需再进行验证码校验
        List<Object> cacheList = redisService.getCacheList(CHECK_CODE_IP);
        if (cacheList.isEmpty()) {
            cacheList = new ArrayList<>();
        }
        cacheList.add(IpUtils.getIp(request));
        redisService.setCacheList(CHECK_CODE_IP, cacheList);
        //通过删除验证码
        redisService.deleteObject(key);
        return ResponseResult.success("验证成功");
    }


    //    -----自定义方法开始-------

    /**
     * 删除文章后的一些同步删除
     *
     * @param ids
     */
    private void deleteAfter(List<Long> ids) {
        blogTagMapper.deleteByArticleIds(ids);
        //异步删除es文章
        elasticsearchUtils.delete(ids);
    }

    /**
     * 将数据库不存在的标签新增
     *
     * @param article
     * @return
     */
    private List<Long> getTagsList(ArticleDTO article) {
        List<Long> tagList = new ArrayList<>();
        article.getTags().forEach(item -> {
            BlogTag tags = blogTagMapper.selectOne(new QueryWrapper<BlogTag>().eq(FieldConstants.NAME, item));
            if (tags == null) {
                tags = BlogTag.builder().name(item).sort(0).build();
                blogTagMapper.insert(tags);
            }
            tagList.add(tags.getId());
        });
        return tagList;
    }

    /**
     * 如果分类不存在则新增
     *
     * @param categoryName
     * @return
     */
    private Long savaCategory(String categoryName) {
        BlogCategory category = categoryMapper.selectOne(new QueryWrapper<BlogCategory>().eq(FieldConstants.NAME, categoryName));
        if (category == null) {
            category = BlogCategory.builder().name(categoryName).sort(0).build();
            categoryMapper.insert(category);
        }
        return category.getId();
    }
}
